1   /*
2    * Copyright (C) 2012 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.hash;
18  
19  import com.google.caliper.BeforeExperiment;
20  import com.google.caliper.Benchmark;
21  import com.google.caliper.Param;
22  
23  import java.util.Random;
24  import java.util.zip.Adler32;
25  import java.util.zip.CRC32;
26  import java.util.zip.Checksum;
27  
28  /**
29   * Benchmarks for comparing {@link Checksum}s and {@link HashFunction}s that wrap {@link Checksum}s.
30   *
31   * <p>Parameters for the benchmark are: <ul> <li>size: The length of the byte array to hash. </ul>
32   *
33   * @author Colin Decker
34   */
35  public class ChecksumBenchmark {
36  
37    // Use a constant seed for all of the benchmarks to ensure apples to apples comparisons.
38    private static final int RANDOM_SEED = new Random().nextInt();
39  
40    @Param({"10", "1000", "100000", "1000000"})
41    private int size;
42  
43    private byte[] testBytes;
44  
45    @BeforeExperiment
46    void setUp() {
47      testBytes = new byte[size];
48      new Random(RANDOM_SEED).nextBytes(testBytes);
49    }
50  
51    // CRC32
52  
53    @Benchmark byte crc32HashFunction(int reps) {
54      return runHashFunction(reps, Hashing.crc32());
55    }
56  
57    @Benchmark byte crc32Checksum(int reps) throws Exception {
58      byte result = 0x01;
59      for (int i = 0; i < reps; i++) {
60        CRC32 checksum = new CRC32();
61        checksum.update(testBytes);
62        result ^= checksum.getValue();
63      }
64      return result;
65    }
66  
67    // Adler32
68  
69    @Benchmark byte adler32HashFunction(int reps) {
70      return runHashFunction(reps, Hashing.adler32());
71    }
72  
73    @Benchmark byte adler32Checksum(int reps) throws Exception {
74      byte result = 0x01;
75      for (int i = 0; i < reps; i++) {
76        Adler32 checksum = new Adler32();
77        checksum.update(testBytes);
78        result ^= checksum.getValue();
79      }
80      return result;
81    }
82  
83    // Helpers + main
84  
85    private byte runHashFunction(int reps, HashFunction hashFunction) {
86      byte result = 0x01;
87      // Trick the JVM to prevent it from using the hash function non-polymorphically
88      result ^= Hashing.crc32().hashInt(reps).asBytes()[0];
89      result ^= Hashing.adler32().hashInt(reps).asBytes()[0];
90      for (int i = 0; i < reps; i++) {
91        result ^= hashFunction.hashBytes(testBytes).asBytes()[0];
92      }
93      return result;
94    }
95  }